//
//  KXML.m
//  Ghac 4S
//
//  Created by apple on 11-9-6.
//  Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//

#import "KXML.h"
#import "KXMLNode.h"

@implementation KXML
-(id)initWithData:(NSData *)data
{
    if((self = [super init]))
    {
        [m_xmlParser release];
        m_xmlParser = [[NSXMLParser alloc] initWithData:data];
        [m_xmlParser setDelegate:self];
        [m_xmlParser parse];
    }
    return self;
    
}

-(id)initWithContentsOfURL:(NSURL*)path
{
    if((self = [super init]))
    {
        [m_xmlParser release];
        m_xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:path];
        [m_xmlParser setDelegate:self];
         [m_xmlParser parse];
    }
    return self;
}
-(id)initWithStream:(NSInputStream*)stream
{
    if((self = [super init]))
    {
        [m_xmlParser release];
        m_xmlParser = [[NSXMLParser alloc] initWithStream:stream];
        [m_xmlParser setDelegate:self];
         [m_xmlParser parse];
    }
    return self;
    
}
-(id)initWithString:(NSString *)str
{
    if ((self = [self initWithData:[str dataUsingEncoding:NSUTF8StringEncoding]]))
    {
        
    }
    return self;
}
-(NSArray *)arrayByXPath:(KXPath *)path
{
    return [m_rootNode arrayByXPath:path];
}
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
//    NSLog(@"start document");
    [m_NodeStack release];
    m_NodeStack = [[NSMutableArray alloc] init];
    m_stringBuffList = [[NSMutableArray alloc] init];
}
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
//    NSLog(@"end document");
    [m_NodeStack removeAllObjects];
    [m_NodeStack release];
    m_NodeStack = nil;
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{

    KXMLNode* node = [[KXMLNode alloc] init];
    node.__name__ = elementName;
    NSMutableDictionary* dic = [[NSMutableDictionary alloc] initWithDictionary:attributeDict];
    node.__attributes__ = dic;
    [m_NodeStack addObject:node];
    NSMutableString* stringBuff = [[NSMutableString alloc] init];
    [m_stringBuffList addObject:stringBuff];
    [stringBuff release];
    [node release];
    [dic release];
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    [[m_stringBuffList lastObject] appendString:string];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    NSString* trimedStr = [[m_stringBuffList lastObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    
    
    KXMLNode* node = [m_NodeStack.lastObject retain];
    [m_NodeStack removeObject:node];
    if (trimedStr.length == 0)
    {
        node.__type__ = KN_ELEMENT_NODE;
    }
    else
    {
        node.__type__ = KN_TEXT_NODE;
        
        double value;
        NSScanner* scan = [NSScanner scannerWithString:trimedStr];
        BOOL result = [scan scanDouble:&value];
        BOOL isEnd = [scan isAtEnd];

        if (result && isEnd)
        {
            node.__nodeValue__ = [NSNumber numberWithDouble:value];
        }
        else
        {
            node.__nodeValue__ = trimedStr;
        }
        
    }
    
    if (m_NodeStack.count > 0)
    {
        KXMLNode* parentNode = [m_NodeStack lastObject];
        [parentNode.__childrens__ addObject:node];
        node.__parent__ = parentNode;
    }
    else
    {
        if (m_rootNode != nil)
        {
            [m_rootNode release];
        }
        m_rootNode = [node retain];
    }
    [node release];
    [m_stringBuffList removeObject:[m_stringBuffList lastObject]];
}
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"%@", parseError);
}
-(id)valueForUndefinedKey:(NSString *)key
{
    return [m_rootNode valueForUndefinedKey:key];
}
-(NSString *)description
{
    return m_rootNode.description;
}
-(void)dealloc
{
    if (m_rootNode != nil) [m_rootNode release];
    if (m_xmlParser != nil)[m_xmlParser release];
    if (m_NodeStack != nil)[m_NodeStack release];
    if (m_stringBuffList != nil)[m_stringBuffList release];
    [super dealloc];
}
@end
